﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using WeifenLuo.WinFormsUI.Docking;

namespace SysSUFront
{
    public partial class LogDock : DockContent
    {
        #region Singleton

        private static readonly object padlock = new object();
        private static LogDock instance;

        public static LogDock Default
        {
            get
            {
                lock (padlock)
                {
                    if (instance == null || instance.IsDisposed)
                    {
                        if (instance != null)
                            instance.Destroy();

                        instance = new LogDock();
                    }

                    return instance;
                }
            }
        }

        private LogDock()
        {
            InitializeComponent();
            Logger.Default.Out = TextBox;
        }

        public void Destroy()
        {
            Dispose(true);
        }

        #endregion

        private int lastLength;

        public RichTextBox TextBox
        {
            get { return txtLog; }
        }

        private void formatOutput(int start)
        {
            try
            {
                #region Message Type

                int i = txtLog.Find("DEBUG", start, RichTextBoxFinds.MatchCase);
                while (i > -1)
                {
                    txtLog.SelectionFont = new Font("Courier New", 9, FontStyle.Bold);
                    txtLog.SelectionColor = Color.Blue;
                    i = txtLog.Find("DEBUG", i + 1, RichTextBoxFinds.MatchCase);
                }

                i = txtLog.Find("INFO", start, RichTextBoxFinds.MatchCase);
                while (i > -1)
                {
                    txtLog.SelectionFont = new Font("Courier New", 9, FontStyle.Bold);
                    txtLog.SelectionColor = Color.Yellow;
                    i = txtLog.Find("INFO", i + 1, RichTextBoxFinds.MatchCase);
                }

                i = txtLog.Find("WARN", start, RichTextBoxFinds.MatchCase);
                while (i > -1)
                {
                    txtLog.SelectionFont = new Font("Courier New", 9, FontStyle.Bold);
                    txtLog.SelectionColor = Color.Orange;
                    i = txtLog.Find("WARN", i + 1, RichTextBoxFinds.MatchCase);
                }

                i = txtLog.Find("ERROR", start, RichTextBoxFinds.MatchCase);
                while (i > -1)
                {
                    txtLog.SelectionFont = new Font("Courier New", 9, FontStyle.Bold);
                    txtLog.SelectionColor = Color.Red;
                    i = txtLog.Find("ERROR", i + 1, RichTextBoxFinds.MatchCase);
                }

                #endregion

                #region Result

                i = txtLog.Find("NOT TESTED", start, RichTextBoxFinds.MatchCase);
                while (i > -1)
                {
                    txtLog.SelectionFont = new Font("Courier New", 9, FontStyle.Bold);
                    txtLog.SelectionColor = Color.DarkGray;
                    i = txtLog.Find("NOT TESTED", i + 1, RichTextBoxFinds.MatchCase);
                }

                i = txtLog.Find("PASSED", start, RichTextBoxFinds.MatchCase);
                while (i > -1)
                {
                    txtLog.SelectionFont = new Font("Courier New", 9, FontStyle.Bold);
                    txtLog.SelectionColor = Color.DarkGreen;
                    i = txtLog.Find("PASSED", i + 1, RichTextBoxFinds.MatchCase);
                }

                i = txtLog.Find("FAILED", start, RichTextBoxFinds.MatchCase);
                while (i > -1)
                {
                    txtLog.SelectionFont = new Font("Courier New", 9, FontStyle.Bold);
                    txtLog.SelectionColor = Color.Red;
                    i = txtLog.Find("FAILED", i + 1, RichTextBoxFinds.MatchCase);
                }

                #endregion

                #region Sync

                i = txtLog.Find("[UPDATE]", start, RichTextBoxFinds.MatchCase);
                while (i > -1)
                {
                    txtLog.SelectionFont = new Font("Courier New", 9, FontStyle.Bold);
                    txtLog.SelectionColor = Color.Blue;
                    i = txtLog.Find("[UPDATE]", i + 1, RichTextBoxFinds.MatchCase);
                }

                i = txtLog.Find("[COMMIT]", start, RichTextBoxFinds.MatchCase);
                while (i > -1)
                {
                    txtLog.SelectionFont = new Font("Courier New", 9, FontStyle.Bold);
                    txtLog.SelectionColor = Color.Blue;
                    i = txtLog.Find("[COMMIT]", i + 1, RichTextBoxFinds.MatchCase);
                }

                i = txtLog.Find("[REVERT]", start, RichTextBoxFinds.MatchCase);
                while (i > -1)
                {
                    txtLog.SelectionFont = new Font("Courier New", 9, FontStyle.Bold);
                    txtLog.SelectionColor = Color.Blue;
                    i = txtLog.Find("[REVERT]", i + 1, RichTextBoxFinds.MatchCase);
                }

                #endregion

                txtLog.Select(txtLog.TextLength, 0);
                txtLog.ScrollToCaret();
            }
            catch { }
        }

        public void Find(string text)
        {
            if (!String.IsNullOrEmpty(text))
            {
                RichTextBoxFinds rtbf = RichTextBoxFinds.None;
                if (btnMatchCase.Checked)
                {
                    rtbf |= RichTextBoxFinds.MatchCase;
                }
                if (btnMatchWholeWord.Checked)
                {
                    rtbf |= RichTextBoxFinds.WholeWord;
                }

                int startPos = txtLog.SelectionStart + txtLog.SelectionLength;
                startPos = txtLog.Find(text, startPos, rtbf);
                if (!(startPos > 0))
                {
                    startPos = 0;
                    startPos = txtLog.Find(text, startPos, rtbf);
                }
                if (startPos > -1)
                {
                    txtLog.Select(startPos, text.Length);
                    txtLog.ScrollToCaret();
                    txtLog.Focus();
                }
            }
        }

        private void btnClear_Click(object sender, EventArgs e)
        {
            lastLength = 0;
            txtLog.Text = string.Empty;
        }

        private void tbxFind_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyData == Keys.F3 || e.KeyData == Keys.Enter)
            {
                Find(tbxFind.Text);
            }
        }

        private void btnFind_Click(object sender, EventArgs e)
        {
            Find(tbxFind.Text);
        }

        private void txtLog_TextChanged(object sender, EventArgs e)
        {
            formatOutput(lastLength);
            lastLength = txtLog.Text.Length;
        }

        private void txtLog_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyData == Keys.F3 || e.KeyData == Keys.Enter)
            {
                btnFind.PerformClick();
            }
        }
    }
}
